package k8s

import (
	"context"

	appsv1 "k8s.io/api/apps/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
)

func (k *K8sClient) ListDeploymentsByLabels(namespace string, labelsMap map[string]string) ([]appsv1.Deployment, error) {
	options := metav1.ListOptions{
		LabelSelector: labels.SelectorFromSet(labelsMap).String(),
	}

	deploys, err := k.Clientset.AppsV1().Deployments(namespace).List(context.TODO(), options)
	if err != nil {
		return nil, err
	}

	return deploys.Items, nil
}

func (k *K8sClient) DeleteDeploymentsByLabels(namespace string, labelsMap map[string]string, gracePeriod int) error {
	gracePeriodSeconds := int64(gracePeriod)
	deleteOpts := metav1.DeleteOptions{
		GracePeriodSeconds: &gracePeriodSeconds,
	}

	listOpts := metav1.ListOptions{
		LabelSelector: labels.SelectorFromSet(labelsMap).String(),
	}

	return k.Clientset.AppsV1().Deployments(namespace).DeleteCollection(context.TODO(), deleteOpts, listOpts)
}

func (k *K8sClient) CreateDeployment(deploy *appsv1.Deployment) (*appsv1.Deployment, error) {
	return k.Clientset.AppsV1().Deployments(deploy.Namespace).Create(context.TODO(), deploy, metav1.CreateOptions{})
}

func (k *K8sClient) CreateOrUpdateDeployment(deploy *appsv1.Deployment) (*appsv1.Deployment, error) {
	old, err := k.Clientset.AppsV1().Deployments(deploy.Namespace).Get(context.TODO(), deploy.Name, metav1.GetOptions{})
	if err == nil {
		// TODO equal
		if deploy.ResourceVersion == "" {
			deploy.ResourceVersion = old.ResourceVersion
		}
		return k.Clientset.AppsV1().Deployments(deploy.Namespace).Update(context.TODO(), deploy, metav1.UpdateOptions{})
	}

	new, err := k.CreateDeployment(deploy)
	if errors.IsAlreadyExists(err) {
		return k.CreateOrUpdateDeployment(deploy)
	}

	return new, err
}
